package edu.hawaii.halealohacli.kmj;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.wattdepot.client.WattDepotClient;

/**
 * Tests CommandParser's functions. Currently only tests functionality added in version 2.0 of 
 * hale-aloha-cli-kmj.
 * 
 * @author Jordan Takayama
 */
public class TestCommandParser {
  
  /**
   * The URL of the WattDepot server.
   */
  private String url = "http://server.wattdepot.org:8190/wattdepot/";
  
  /**
   * A WattDepot client which connects to the server.
   */
  private WattDepotClient sampleClient = new WattDepotClient(url);
  
  /**
   * A CommandParser object used for testing.
   */
  CommandParser testCommand;
    
  /**
   * A default location name to use in testing.
   */
  private String sourceName = "Lehua";

  /**
   * A second location name to use in testing.
   */
  private String altSourceName = "Mokihana";
  
  /**
   * A default baseline request date to use in testing. In the event of a server crash (or switching
   * to a different server) developers may need to change this date to a valid one to compensate for
   * the unavailability of data for this date. The current value of testDate is "2011-12-01".
   */
  private String testDate = "2011-12-01";
  
  /**
   * Tests the setBaseline method and checks that it correctly sets the Baseline stored by 
   * CommandParser.
   */
  @Test
  public void testSetBaseline() {
    // This implementation of CommandParser does not actually throw Exceptions, printing error 
    // messages instead. However, a successful setBaseline call should call the SetBaseline
    // constructor and initialize the baseline data stored by CommandParser.
    testCommand = new CommandParser(sampleClient);
    
    // Test for null input.
    System.out.println("Testing setBaseline for null input (this should fail).");
    testCommand.setBaseline("");
    assertNull("Blank input should be caught by CommandParser.", testCommand.storedBaseline);
    assertFalse("isBaselineSet should be false if no arguments are given.", 
        testCommand.isBaselineSet);
    testCommand.storedBaseline = null;
    testCommand.isBaselineSet = false;
    
    // Test for location name only, with space.
    System.out.println("Testing setBaseline for location only, with a space at the end.");
    testCommand.setBaseline(sourceName + " ");
    assertNotNull("Date is an optional argument, the method call should succeed.", 
        testCommand.storedBaseline);
    assertTrue("isBaselineSet should be true because passing only a location should succeed.", 
        testCommand.isBaselineSet);
    testCommand.storedBaseline = null;
    testCommand.isBaselineSet = false;
    
    // Test for location name only, with no space at the end.
    System.out.println("Testing setBaseline for location only, with no space at the end.");
    testCommand.setBaseline(altSourceName);
    assertNotNull("Date is an optional argument, the method call should succeed.", 
        testCommand.storedBaseline);
    assertTrue("isBaselineSet should be true because passing only a location should succeed.", 
        testCommand.isBaselineSet);
    testCommand.storedBaseline = null;
    testCommand.isBaselineSet = false;
    
    // Test for invalid location.
    System.out.println("Testing setBaseline for nonexistent location (this should fail).");
    testCommand.setBaseline("Nowhere " + testDate);
    assertNull("setBaseline should not collect data for an unsupported location.", 
        testCommand.storedBaseline);
    assertFalse("isBaselineSet should be false if baseline data is unavailable for a source.", 
        testCommand.isBaselineSet);
    testCommand.storedBaseline = null;
    testCommand.isBaselineSet = false;
    
    // Test for invalid date.
    System.out.println("Testing setBaseline for nonexistent date (this should succeed anyway).");
    testCommand.setBaseline(sourceName + " 2011-02-29");
    assertNotNull("setBaseline should use a default date if the given date does not work.", 
        testCommand.storedBaseline);
    assertTrue("isBaselineSet should be true if baseline data is collected for a default date", 
        testCommand.isBaselineSet);
    testCommand.storedBaseline = null;
    testCommand.isBaselineSet = false;
    
    // Test for too many parameters.
    System.out.println("Testing setBaseline for more than two arguments (this should fail).");
    testCommand.setBaseline(sourceName + " " + testDate + " " + altSourceName);
    assertNull("setBaseline should not collect data when given too many arguments.", 
        testCommand.storedBaseline);
    assertFalse("isBaselineSet should be false if baseline data is not collected when too many " 
        + "arguments are given.", testCommand.isBaselineSet);
    testCommand.storedBaseline = null;
    testCommand.isBaselineSet = false;
  }

  /**
   * Tests that the help method runs without error.
   */
  @Test
  public void testHelp() {
    testCommand = new CommandParser(sampleClient);
    System.out.println("Testing help:");
    testCommand.help();
  }

  /**
   * Tests that the errorMessage method runs without error.
   */
  @Test
  public void testErrorMessage() {
    testCommand = new CommandParser(sampleClient);
    System.out.println("Testing errorMessage:");
    testCommand.errorMessage("[Not really an error]");
  }

}
